#include "cinputvideostream.h"

namespace buola { namespace media { namespace ffmpeg {

CInputVideoStream::CInputVideoStream(AVStream* pAV)
{
    mAV=pAV;

    mFrame=avcodec_alloc_frame();
    mFrameOut=avcodec_alloc_frame();
    mConvert=nullptr;

    AVCodec *lCodec=avcodec_find_decoder(mAV->codec->codec_id);
    if(!lCodec)
        throw XNotFound("can't find a suitable codec");

    if(avcodec_open2(mAV->codec,lCodec,nullptr)<0)
        throw XInternal("can't open codec");
}

void CInputVideoStream::SetPorts(blackbox::CDataOut< img::CImage_rgb8 >* pOut, blackbox::CClockOut* pClock)
{
    oVideo=pOut;
    kVideo=pClock;
}

void CInputVideoStream::ProcessPacket(AVPacket* pPacket)
{
    msg_info() << "video packet\n";

    int lFrameFinished=0;

    avcodec_decode_video2(mAV->codec,mFrame,&lFrameFinished,pPacket);

    if(lFrameFinished)
    {
        if(!mConvert)
        {
            mConvert=sws_getContext(mAV->codec->width,mAV->codec->height,mAV->codec->pix_fmt,
                                    mAV->codec->width,mAV->codec->height,PIX_FMT_RGB24,SWS_BICUBIC,
                                    nullptr,nullptr,nullptr);
        }

        img::CImage_rgb8 lImage(CSize_i(mAV->codec->width,mAV->codec->height),oVideo->Allocator());
        avpicture_fill((AVPicture*)mFrameOut,lImage.RawBytes(),PIX_FMT_RGB24,mAV->codec->width,mAV->codec->height);
        sws_scale(mConvert,mFrame->data,mFrame->linesize,0,mAV->codec->height,mFrameOut->data,mFrameOut->linesize);

        *oVideo=std::move(lImage);
        kVideo->Trigger();
    }
}

/*namespace ffmpeg*/ } /*namespace media*/ } /*namespace buola*/ }
